package utils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public abstract class ConcurrentHarness {

	protected static final int CYCLES = 100000;
	protected ExecutorService executor;
	
	@Before
	public void initExecutor() {
		executor = new ThreadPoolExecutor(4, 4, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CYCLES));
	}
	
	@Test
	public void submitTasks() {
		for (int i = 0; i < CYCLES; ++i) {
			executor.submit(newTask());
		}
	}

	@After
	public void collectResults() throws InterruptedException {
		waitAllTaks();
		checkResults();
	}
	
	private void waitAllTaks() throws InterruptedException {
		executor.shutdown();
		boolean terminated = executor.awaitTermination(20, TimeUnit.SECONDS);
		assertTrue("Not finished",terminated);
	}
	
	
	protected abstract void checkResults();

	protected abstract Runnable newTask();

}